package su.order.service.impl;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Map;

import net.kuakao.core.exception.DataBaseException;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;

import su.base.Constants;
import su.order.dao.IOrderDAO;
import su.order.dao.IOrderProductDAO;
import su.order.dto.OrderDto;
import su.order.dto.OrderProductDto;
import su.order.entity.OrderEntity;
import su.order.entity.OrderProductEntity;
import su.order.service.OrderService;
import su.order.util.OrderUtil;
import su.product.dao.IProductDAO;
import su.product.dao.IProductPriceDAO;
import su.product.entity.Product;
import su.product.entity.ProductPrice;
import su.tool.FunctionUtil;
import su.tool.SuDateUtils;
import su.tool.SuDoubleUtils;

public class OrderServiceImpl implements OrderService {
	
	@Autowired
	private IOrderDAO orderDAO;
	
	@Autowired
	private IOrderProductDAO orderProductDAO;
	
	@Autowired
	private IProductDAO productDAO;
	
	@Autowired
	private IProductPriceDAO productPriceDAO;
	
	protected final Log log = LogFactory.getLog(getClass());

	public List<Map<String,Object>> queryOrderByPage(OrderDto orderDto, Model model) throws Exception {
		return orderDAO.queryByPage(orderDto);
	}

	public OrderEntity getOrderBaseInfoById(int orderId) throws Exception {
		OrderEntity orderEntity = orderDAO.getById(orderId);
		return orderEntity;
	}
	
	public OrderEntity getOrderAllInfoById(int orderId) throws Exception{
		OrderEntity orderEntity = orderDAO.getById(orderId);
		List<OrderProductEntity> orderProductEntities = orderProductDAO.getAllByOrderId(orderId);
		orderEntity.setOrderProductEntities(orderProductEntities);
		return orderEntity;
	}

	public void saveOrder(OrderDto orderDto, Model model) throws Exception {
//		sutest
//		System.out.println("----baseinfo------");
//		System.out.println("orderId==="+orderDto.getId());
//		System.out.println("customerId==="+orderDto.getCustomerId());
//		System.out.println("ywyId==="+orderDto.getYwyId());
//		System.out.println("operator====="+orderDto.getOperator());
//		System.out.println("contact====="+orderDto.getContact());
//		System.out.println("invoice====="+orderDto.getInvoice());
//		System.out.println("odesc====="+orderDto.getOdesc());
//		System.out.println("orderProducts====="+orderDto.getOrderProducts());
//		System.out.println("------batchinfo-----");
//		JSONArray jsonArray = JSONArray.fromObject("["+orderDto.getOrderProducts()+"]");
//		for(Object o : JSONArray.toCollection(jsonArray)){
//			OrderProductEntity tb = (OrderProductEntity)JSONObject.toBean(JSONObject.fromObject(o),OrderProductEntity.class);
//			System.out.println("productId==="+tb.getProductId()+",num==="+tb.getNum()+",opprice==="+tb.getOpprice()+",packname==="+tb.getPackname()+",custname==="+tb.getCustname());
//		}
//		sutest end		
		//基本信息
		OrderEntity orderEntity = orderDto.toOrderEntity();
		int orderId = orderEntity.getId();
		if(orderId == 0) {
			orderEntity.setOrderCreateTime(new Date());
			orderEntity.setOrderType(OrderDto.ORDER_TYPE_SALE);
			orderEntity.setStatus(OrderDto.ORDER_STATUS_NEW);
			orderEntity.setInvoiceStatus(OrderDto.ORDER_INVOICE_STATUS_READY);
			orderEntity.setSettlementStatus(OrderDto.ORDER_SETTLEMENT_STATUS_READY);
			orderId = orderDAO.insert(orderEntity);
		} else {
			orderDAO.update(orderEntity);
		}
		//添加订单产品信息(新增项在此处理，修改项与删除项单独处理)
		String orderProducts = orderDto.getOrderProducts();
		if(StringUtils.isBlank(orderProducts))return;
		JSONArray jsonArray = JSONArray.fromObject("["+orderProducts+"]");
		OrderProductEntity tb;
		Product p;
		for(Object o : JSONArray.toCollection(jsonArray)){
			tb = (OrderProductEntity)JSONObject.toBean(JSONObject.fromObject(o),OrderProductEntity.class);
			tb.setOrderId(orderId);
			tb.setStorageStatus(OrderProductDto.STORAGE_STATUS_NO);
			tb.setInvoiceStatus(OrderProductDto.INVOICE_STATUS_NO);
			p = productDAO.getById(tb.getProductId());
			if(p == null){
				throw new DataBaseException("产品ID为"+tb.getProductId()+"的产品信息没找到");
			}
			//包装件数
			if(tb.getNum()<=0){
				throw new DataBaseException("产品ID为"+tb.getProductId()+"的产品订购数量为0");
			}
			if(p.getPackstandard() <= 0){
				throw new DataBaseException("产品ID为"+tb.getProductId()+"的产品的包装规格数据有误，请修改");
			}
			tb.setPackageNum((int)FunctionUtil.div(tb.getNum()-1, p.getPackstandard(), 0)+1);
			//快照信息
			tb.setCcprice(p.getPrice());
			tb.setPackstandard(p.getPackstandard());
			tb.setFreightType(p.getFreighttype());
			tb.setFreightTypeValue(OrderUtil.getProductFreightTypeContent(p.getFreighttype()));
			tb.setPfunc(p.getPfunc());
			tb.setFuncTcCon(OrderUtil.getFuncTcCon(p.getPfunc()));
			tb.setFuncTaxCon(OrderUtil.getFuncTaxCon(p.getPfunc()));
			tb.setFuncMarginCon(OrderUtil.getFuncMarginCon(p.getPfunc()));
			tb.setMinPayment(p.getMinpayment());
			
			orderProductDAO.insert(tb);
		}
		//修改订单统计信息及订单项相应变化信息
		this.updateOrderTotalInfos(orderId);
	}
	
	public void updateOrderTotalInfos(int orderId) throws Exception{
		if(orderId <= 0){
			throw new DataBaseException("修改的订单不存在，请刷新页面重新操作");
		}
		OrderEntity orderEntity = orderDAO.getById(orderId);
		if(orderEntity == null){
			throw new DataBaseException("ID为"+orderId+"的订单不存在，请联系管理员");
		}
		List<OrderProductEntity> orderProducts = orderProductDAO.getAllByOrderId(orderId);
		if(orderProducts == null || orderProducts.isEmpty()){
			throw new DataBaseException("ID为"+orderId+"的订单没有产品信息，请联系管理员");
		}
		//计算订单的运费基数
		double base = 0;
		double totalShipment = orderEntity.getTotalShipment();
		if(totalShipment > 0){//有运费时
			for(OrderProductEntity orderProduct : orderProducts){
				base += orderProduct.getNum()*orderProduct.getFreightTypeValue();
			}			
		}
		log.debug("====suMsg:OrderServiceImpl.updateOrderTotalInfos(),orderId==="+orderId+",freight base==="+base);
		double orderProductFreight = 0;//运费
		double payment = 0;//理论提成
		double tax = 0;//理论税金
		double margin = 0;//理论利润
		for(OrderProductEntity orderProductEntity : orderProducts){
			//运费
			if(totalShipment > 0){
				orderProductFreight = totalShipment*orderProductEntity.getNum()*orderProductEntity.getFreightTypeValue()/base;
				orderProductFreight = SuDoubleUtils.double45(orderProductFreight, 2);
			}
			//理论提成
			payment = this.countPayment(orderProductEntity, orderEntity, orderProductFreight);
			//理论税金
			tax = this.countTax(orderProductEntity, orderEntity, orderProductFreight,payment);
			//
			if("1".equals(orderProductEntity.getPfunc()) || "4".equals(orderProductEntity.getPfunc())){
				payment = FunctionUtil.sub(payment, tax);
			}
			//理论利润
			margin = this.countMargin(orderProductEntity, payment);
			
			//修改
			orderProductEntity.setFreight(orderProductFreight);
			orderProductEntity.setPayment(payment);
			orderProductEntity.setTax(tax);
			orderProductEntity.setMargin(margin);
			orderProductDAO.updateOrderProductFunctionInfo(orderProductEntity);
		}

	}
	/**
	 * 计算理论利润
	 * @param orderProductEntity
	 * @param payment
	 * @return
	 */
	private double countMargin(OrderProductEntity orderProductEntity,double payment){
		double num = orderProductEntity.getNum();
		if(num == 0)return 0;
		String funcMarginCon = orderProductEntity.getFuncMarginCon();
		if(StringUtils.isBlank(funcMarginCon) || "0".equals(funcMarginCon))return 0;
		
		double gsPayment = orderProductEntity.getGsPayment();
		funcMarginCon = funcMarginCon.replaceAll("GSTL", String.valueOf(gsPayment*num))
						.replaceAll("SJ", String.valueOf(orderProductEntity.getOpprice()))
						.replaceAll("CCJ", String.valueOf(orderProductEntity.getCcprice()))
						.replaceAll("XSL", String.valueOf(num))
						.replaceAll("TL", String.valueOf(payment));
		double margin = SuDoubleUtils.double45(FunctionUtil.suUse(funcMarginCon), 2);
		return margin;
	}
	/**
	 * 计算理论税金
	 * @param orderProductEntity
	 * @param orderEntity
	 * @param orderProductFreight
	 * @param payment
	 * @return
	 */
	private double countTax(OrderProductEntity orderProductEntity,OrderEntity orderEntity,double orderProductFreight,double payment){
		if(orderEntity.getInvoice() != OrderDto.ORDER_INVOICE_YES)return 0;
		double num = orderProductEntity.getNum();
		if(num == 0)return 0;
		String funcTaxCon = orderProductEntity.getFuncTaxCon();
		if(StringUtils.isBlank(funcTaxCon) || "0".equals(funcTaxCon))return 0;
		
		double tax = 0;
		funcTaxCon = funcTaxCon.replaceAll("TCBZ", String.valueOf(payment/num))
					.replaceAll("YF", String.valueOf(orderProductFreight/num)).replaceAll("SJ", String.valueOf(orderProductEntity.getOpprice()))
					.replaceAll("CCJ", String.valueOf(orderProductEntity.getCcprice()));
		tax = FunctionUtil.suUse(funcTaxCon);
		tax = SuDoubleUtils.double45(tax*num, 2);
		
		return tax;
	}
	/**
	 * 计算理论提成
	 * @param orderProduct 订单产品信息
	 * @param orderEntity 订单信息
	 * @param orderProductFreight 订单产品运费
	 * @return
	 * @throws SQLException 
	 */
	private double countPayment(OrderProductEntity orderProductEntity,OrderEntity orderEntity,double orderProductFreight) throws SQLException{
		double num = orderProductEntity.getNum();
		if(num == 0)return 0;
		String funcTcCon = orderProductEntity.getFuncTcCon();
		if(StringUtils.isBlank(funcTcCon) || "0".equals(funcTcCon))return 0;
		
		double payment = 0;
		double gsPayment = 0;//需要计算的理论公司提成
		funcTcCon = funcTcCon.replaceAll("ZSJ", String.valueOf(orderProductEntity.getOpprice()*num))
		.replaceAll("SJ", String.valueOf(orderProductEntity.getOpprice())).replaceAll("XSL", String.valueOf(num))
		.replaceAll("YF", String.valueOf(orderProductFreight)).replaceAll("FP", orderEntity.getInvoice()==OrderDto.ORDER_INVOICE_YES?"1":"0")
		.replaceAll("CCJ", String.valueOf(orderProductEntity.getCcprice()));
	
		if("3".equals(orderProductEntity.getPfunc())){//公式3不需要查找产品售价标准,由公式直接得出提成
			payment = FunctionUtil.suUse(funcTcCon);
		}else{
			double price = FunctionUtil.suUse(funcTcCon)/num;//单件产品的理论提成
			price = SuDoubleUtils.double45(price, 2);
			price = OrderUtil.get50Value(price);
			List<ProductPrice> productPrices = productPriceDAO.getPriceByProductId(orderProductEntity.getProductId());
			if(productPrices == null || productPrices.isEmpty()){
				log.error("suMsg:OrderServiceImpl.countPayment(),productId==="+orderProductEntity.getProductId()+",it's product prices is none");
				return 0;
			}
			Date shipmentTime = orderEntity.getShipmentTime()==null ? new Date() : orderEntity.getStorageTime();
			double pm = 0;
			for(ProductPrice productPrice : productPrices){
				if(productPrice.getStatus() != Constants.STATUS_ENABLE){
					continue;
				}
				if((productPrice.getTimefrom().before(shipmentTime) || SuDateUtils.getDiffDay(productPrice.getTimefrom(), shipmentTime)==0) 
						&& (productPrice.getTimeto()==null || productPrice.getTimeto().after(shipmentTime))){
					if(price >= productPrice.getPriceto()){
						pm += (productPrice.getPriceto() - productPrice.getPricefrom())*productPrice.getPayment()/100;
						log.debug(productPrice.getPriceto()+"-"+productPrice.getPricefrom()+"*"+productPrice.getPayment());
						gsPayment += (productPrice.getPriceto() - productPrice.getPricefrom())*(1 - productPrice.getPayment()/100);
					}else{
						if(price <= productPrice.getPricefrom()){
							continue;
						}else{
							pm += (price - productPrice.getPricefrom())*productPrice.getPayment()/100;
							log.debug(price+"-"+productPrice.getPricefrom()+"*"+productPrice.getPayment());
							gsPayment += (price - productPrice.getPricefrom())*(1 - productPrice.getPayment()/100);
						}
					}
				}
			}
			payment = SuDoubleUtils.double45(num*pm, 2);
		}
		//确保对于该产品的最低提成
		payment = payment/num < orderProductEntity.getMinPayment()/1000 ? orderProductEntity.getMinPayment()/1000*num : payment;
		orderProductEntity.setGsPayment(gsPayment);
		
		return payment;
	}

	public void destroyOrder(int orderId, Map<String,String> msgs) throws Exception {
		if(orderId == 0){
			msgs.put("error","删除失败，订单id为0!");
			return;
		}
		orderDAO.remove(orderId);
	}

}

